package com.avoid.easymqtt.broker;

import com.avoid.easymqtt.common.SystemClock;
import com.avoid.easymqtt.remoting.common.RemotingHelper;
import com.avoid.easymqtt.remoting.netty.NettyServerConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 描述
 *
 * @author avoid@fiture.com
 * @date 2022/5/9
 * @motto Life is so short,do something to make yourself happy,such as coding
 */
public class BrokerStartup {
    private static final Logger log = LoggerFactory.getLogger(RemotingHelper.EASYMQTT_REMOTING);

    public static void main(String[] args) {
        start(createBrokerController(args));
    }

    public static BrokerController start(BrokerController controller) {
        try {
            controller.start();

            String tip = "The broker[" + controller.getBrokerConfig().getBrokerName() + ", "
                + controller.getBrokerAddr() + "] boot success.";

            if (null != controller.getBrokerConfig().getNamesrvAddr()) {
                tip += " and name server is " + controller.getBrokerConfig().getNamesrvAddr();
            }

            log.info(tip);
            System.out.printf("%s%n", tip);
            return controller;
        } catch (Throwable e) {
            e.printStackTrace();
            System.exit(-1);
        }

        return null;
    }

    public static BrokerController createBrokerController(String[] args) {
        try {
            final BrokerConfig brokerConfig = new BrokerConfig();
            final NettyServerConfig nettyServerConfig = new NettyServerConfig();

            final BrokerController controller = new BrokerController(brokerConfig, nettyServerConfig);

            boolean initResult = controller.initialize();
            if (!initResult) {
                controller.shutdown();
                System.exit(-3);
            }
            Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
                private volatile boolean hasShutdown = false;
                private final AtomicInteger shutdownTimes = new AtomicInteger(0);

                @Override
                public void run() {
                    synchronized (this) {
                        log.info("关闭钩子被调用, {}", this.shutdownTimes.incrementAndGet());
                        if (!this.hasShutdown) {
                            this.hasShutdown = true;
                            long beginTime = SystemClock.getNow();
                            controller.shutdown();
                            long consumingTimeTotal = SystemClock.getNow() - beginTime;
                            log.info("关闭easymqtt，消耗总时间(ms): {}", consumingTimeTotal);
                        }
                    }
                }
            }, "ShutdownHook"));

            return controller;
        } catch (Throwable e) {
            e.printStackTrace();
            System.exit(-1);
        }
        return null;
    }
}
